from ctypes import *
from ptk.error import *

ptkdll = cdll.Pyptk

def MdlCurrentGet():
    ProMdlCurrentGet_ = ptkdll.PyProMdlCurrentGet
    ProMdlCurrentGet_.restype = c_int32
    mdl = c_void_p()
    err = ProMdlCurrentGet_(byref(mdl));
    raisePtkError(err)
    return mdl


def MdlNameGet(mdl):
    ProMdlNameGet_ = ptkdll.PyProMdlNameGet
    ProMdlNameGet_.restype = c_int32
    name = create_unicode_buffer(32)
    err=ProMdlNameGet_(mdl,name)
    raisePtkError(err)
    return str(name.value)

def MdlRename(mdl,newname):
    ProMdlRename_ = ptkdll.PyProMdlRename
    ProMdlRename_.restype = c_int32
    name = create_unicode_buffer(newname)
    err=ProMdlRename_(mdl,name)
    raisePtkError(err)

def MdlTypeGet(mdl):
    ProMdlTypeGet = ptkdll.PyProMdlTypeGet
    ProMdlTypeGet.restype = c_int32
    mdltype = c_int(-1)
    err=ProMdlTypeGet(mdl,byref(mdltype))
    raisePtkError(err)
    return mdltype

def MdlLoad(full_path,mtype,ask_user_about_reps):
    ProMdlLoad = ptkdll.PyProMdlLoad
    ProMdlLoad.restype = c_int32
    path = create_unicode_buffer(full_path)
    mtype_p = c_int32(mtype)
    ask_user_about_reps_p = c_int32(ask_user_about_reps)
    mdl = c_void_p()
    err = ProMdlLoad(path,mtype_p,ask_user_about_reps_p,byref(mdl))
    raisePtkError(err)
    return mdl

def MdlDisplay(model):
    ProMdlDisplay = ptkdll.PyProMdlDisplay
    ProMdlDisplay.restype = c_int32
    err=ProMdlDisplay(model)
    raisePtkError(err)

def WindowCurrentGet():
    ProWindowCurrentGet = ptkdll.PyProWindowCurrentGet
    ProWindowCurrentGet.restype = c_int32
    idwnd = c_int(-1)
    err=ProWindowCurrentGet(byref(idwnd))
    raisePtkError(err)
    return idwnd

def WindowRefresh(idwnd):
    ProWindowRefresh = ptkdll.PyProWindowRefresh
    ProWindowRefresh.restype = c_int32
    err=ProWindowRefresh(idwnd)
    raisePtkError(err)


def MenubarMenuAdd(menu_name,
                      untranslated_menu_label,
                        neighbor,
                        add_after_neighbor,
                        filename ):
    ProMenubarMenuAdd_ = ptkdll.PyProMenubarMenuAdd
    ProMenubarMenuAdd_.restype = c_int32
    name = create_string_buffer(menu_name.encode('ascii','ignore'))
    menu_label = create_string_buffer(untranslated_menu_label.encode('ascii','ignore'))
    neighbor_c = create_string_buffer(neighbor.encode('ascii','ignore'))
    add_after_neighbor = c_int(add_after_neighbor)
    filename_w = create_unicode_buffer(filename)
    err = ProMenubarMenuAdd_(name,menu_label,neighbor_c,add_after_neighbor,filename_w)
    raisePtkError(err)

uiCmdCmdActFn = CFUNCTYPE(c_int, c_void_p,c_void_p,c_void_p) 
uiCmdAccessFn = CFUNCTYPE(c_int, c_int)
def CmdActionAdd(action_name,
                action_cb,
                priority,
                access_func,
                allow_in_non_active_window,
                allow_in_accessory_window):
    """ action_cb is a uiCmdCmdActFn,
        access_func is a uiCmdAccessFn,
    """ 
    ProCmdActionAdd = ptkdll.PyProCmdActionAdd
    ProCmdActionAdd.restype = c_int32
    action_name_p = create_string_buffer(action_name.encode('ascii','ignore'))
    priority_p = c_int32(priority)
    allow_in_non_active_window_p = c_int32(allow_in_non_active_window)
    allow_in_accessory_window_p = c_int32(allow_in_accessory_window)
    action_id = c_void_p()
    err = ProCmdActionAdd(action_name_p,action_cb,priority_p,access_func,
                    allow_in_non_active_window_p,allow_in_accessory_window_p,byref(action_id))
    raisePtkError(err)
    return action_id


def MenubarmenuPushbuttonAdd(parent_menu,
                            push_button_name,
                            push_button_label,
                            one_line_help,
                            neighbor,
                            add_after_neighbor,
                            action_id,
                            filename ):
    ProMenubarmenuPushbuttonAdd = ptkdll.PyProMenubarmenuPushbuttonAdd
    ProMenubarmenuPushbuttonAdd.restype = c_int32
    parent_menu_p = create_string_buffer(parent_menu.encode('ascii','ignore'))
    push_button_name_p = create_string_buffer(push_button_name.encode('ascii','ignore'))
    push_button_label_p = create_string_buffer(push_button_label.encode('ascii','ignore'))
    one_line_help_p = create_string_buffer(one_line_help.encode('ascii','ignore'))
    if neighbor:    
        neighbor_p = create_string_buffer(neighbor.encode('ascii','ignore'))
    else:
        neighbor_p = c_void_p()
    add_after_neighbor_p = c_int32(add_after_neighbor)
    filename_w = create_unicode_buffer(filename)
    err=ProMenubarmenuPushbuttonAdd(parent_menu_p,push_button_name_p,push_button_label_p,one_line_help_p
                                ,neighbor_p,add_after_neighbor_p,action_id,filename_w)
    raisePtkError(err)

ProMatrix = c_double*16

class Modelitem(Structure):
    _fields_ = [("type", c_int),
                ("id", c_int),
                ("owner", c_void_p)]
    
def AsmcompAssemble(owner_assembly,component_model,init_pos):
    ProAsmcompAssemble = ptkdll.PyProAsmcompAssemble
    ProAsmcompAssemble.restype = c_int32
    aitem = Modelitem()
    err=ProAsmcompAssemble(owner_assembly,component_model,init_pos,byref(aitem))
    raisePtkError(err)
    return aitem

def AsmcompPositionSet(component_path,component_p,position):
    ProAsmcompPositionSet = ptkdll.PyProAsmcompPositionSet
    ProAsmcompPositionSet.restype = c_int32
    if component_path:    
        component_path_p = c_void_p()
    else:
        component_path_p = c_void_p()
    err=ProAsmcompPositionSet(component_path_p,byref(component_p),position)
    raisePtkError(err)

def AsmcompPositionGet(component_p):
    ProAsmcompPositionGet = ptkdll.PyProAsmcompPositionGet
    ProAsmcompPositionGet.restype = c_int32
    position = ProMatrix()
    err=ProAsmcompPositionGet(byref(component_p),position)
    raisePtkError(err)
    return position

def FeatureDelete(solid,feats,opts):
    ProFeatureDelete = ptkdll.PyProFeatureDelete
    ProFeatureDelete.restype = c_int32
    feat_count = len(feats)
    fetarr = c_int * feat_count
    feat_ids = fetarr()
    for fid in range(feat_count):
        feat_ids[fid] = feats[fid].id
    feat_count_p = c_int32(feat_count)
    num_opts = len(opts)
    fetopt = c_int * num_opts
    delete_opts = fetopt()
    for oid in range(num_opts):
        delete_opts[oid] = opts[oid]
    num_opts_p = c_int32(num_opts)
    err=ProFeatureDelete(solid,feat_ids,feat_count_p,delete_opts,num_opts)
    raisePtkError(err)
